#ifndef SETTINGS_H
#define SETTINGS_H

#include "iobserver.h"

#include <QtCore/QHash>
#include <QtCore/QVariant>

QT_BEGIN_NAMESPACE
class QSettings;
QT_END_NAMESPACE

namespace core
{

class Settings : public QObject, public IObservableObject
{
    Q_OBJECT

public:
    static Settings* getInstance();
    static void destroy();

    void addCategory(const QString& category, const QString& text);
    void removeCategory(const QString& category);

    QString categoryText(const QString& category) const;
    void setCategoryText(const QString& category, const QString& text);

    QList<QString> categories() const;

    void addOption(const QString& category, const QString& name,
        const QString& text, const QVariant& value);
    void removeOption(const QString& category, const QString& name);

    QList<QString> optionsInCategory(const QString& category) const;

    QString optionText(const QString& category,
        const QString& name) const;
    QVariant optionValue(const QString& category,
        const QString& name) const;
    void setOptionText(const QString& category,
        const QString& name, const QString& text);
    void setOptionValue(const QString& category,
        const QString& name, const QVariant& value);

    void read(QSettings* settings);
    void write(QSettings* settings);

    // IObservableObject
    void addObserver(const QString& property, IObserver* observer);
    void removeObserver(const QString& property, IObserver* observer);
    void removeObservers(const QString& property);

private:
    Settings();
    ~Settings();

signals:
    void categoryTextChanged(const QString& category, const
        QString& text);
    void textChanged(const QString& category,
        const QString& name, const QString& text);
    void optionChanged(const QString& category,
        const QString& name, const QVariant& value);

private slots:
    void notifyObservers(const QString& category,
        const QString& name, const QVariant& value);

private:
    QHash<QString, QString> m_categories;
    QHash<QString, QList<QString> > m_options;
    QHash<QPair<QString, QString>, QPair<QString, QVariant> > m_values;
    QHash<QString, QList<IObserver*> > m_observers;
};

} // namespace core

#endif
